"""
EnvironmentPane - PreferencePane for changing the global user environment

This PreferencePane provides an easy to use UI for changeing
~/.MacOSX/environment.plist. This plist is loaded by the loginwindow application
when the user logs in and is used to initialize the "shell" environment.

Note that these variables are also available outside of the Terminal, but not
when the user logs in using SSH.

TODO:
- Undo
"""
import objc
from AppKit import *
from Foundation import *
from PreferencePanes import *
from PyObjCTools import NibClassBuilder, AppHelper
import os
import popdaemon
from launcher import *
from settings import *
from macstuff import *
# Uncomment this during development, you'll get exception tracebacks when
# the Python code fails.
objc.setVerbose(1)


NibClassBuilder.extractClasses("EnvironmentPane")

# Location of the environment.plist


# Template for new keys
NEWTMPL=NSLocalizedString("New_Variable_%d", "")

GREEN = 2
RED = 0

class EnvironmentPane (NibClassBuilder.AutoBaseClass):
	"""
	The 'model/controller' for the "Shell Environment" preference pane
	"""

	#__slots__ = (
	#	'environ',  # The actual environment, as a NSMutableDictionary
	#	'keys',	 # The list of keys, in the right order for the tableView
	#	'changed',  # True if we should save before exitting
	#)

	def initWithBundle_(self, bundle):
		# Our bundle has been loaded, initialize the instance variables.
		# We don't load the environment.plist yet, do that when we're
		# actually selected. That way we can easier pick up manual changes.
		
		self = super(EnvironmentPane, self).initWithBundle_(bundle)
		if self is None: return None
		self.path = bundle.bundlePath()
		NSLog(self.path)
		self.runpath = self.path + BUNDLEPATH
		self.popport = None
		self.poplevel = None
		self.poplogon = None
		
		self.smtplogon = None
		self.smtpport = None
		self.smtplevel = None
		self.popdelay = None
		self.poprunning = False
		self.smtprunning = False
		self.changed = False
		self.timer = None
		self.config = None
		return self
	
	def update(self):
		if self.poprunning:
			self.incomingButton.setTitle_(u"Stop Incoming Mail")
			self.incomingIndicator.setDoubleValue_(GREEN)
			self.incomingDelay.setEnabled_(False)
			self.incomingLevel.setEnabled_(False)
			self.incomingPort.setEnabled_(False)
		else:
			self.incomingButton.setTitle_(u"Start Incoming Mail")
			self.incomingIndicator.setDoubleValue_(RED)
			self.incomingDelay.setEnabled_(True)
			self.incomingLevel.setEnabled_(True)
			self.incomingPort.setEnabled_(True)

		if self.smtprunning:
			self.outgoingButton.setTitle_(u"Stop Outgoing Mail")
			self.outgoingIndicator.setDoubleValue_(GREEN)
			self.outgoingLevel.setEnabled_(False)
			self.outgoingPort.setEnabled_(False)
		else:
			self.outgoingButton.setTitle_(u"Start Outgoing Mail")
			self.outgoingIndicator.setDoubleValue_(RED)
			self.outgoingLevel.setEnabled_(True)
			self.outgoingPort.setEnabled_(True)
			
		
		
	def onTime(self):	
		self.poprunning = isRunning(POP_PID)
		self.smtprunning = isRunning(SMTP_PID)
		self.update()
		
	def start(self):
		if not self.timer:
			interval = 2
			self.timer = NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(interval, self, self.onTime, None, True)
		pass
	
	def stop(self):
		if self.timer:
			self.timer.invalidate()
			self.timer = None

	def loadStartupTemplate(self):
		template = None
		try:
			f  = file(self.runpath+TEMPLATE,'r')
			template = f.read()
		except:
			pass
		return template
			
	def createPopStartupItem(self):
		self.removePopStartupItem()
		launchfile  = os.path.expanduser(STARTUP_DIR+POPLAUNCH_FILE)
		try:
			f = open(launchfile,"w")
			template =  self.loadStartupTemplate()
			content = template%(POPLAUNCH_NAME,self.runpath+'pop.py', 'restart')
			f.write(content)
			f.close()
		except:
			pass
	
	def createSmtpStartupItem(self):
		self.removeSmtpStartupItem()
		launchfile  = os.path.expanduser(STARTUP_DIR+SMTPLAUNCH_FILE)
		try:
			f = open(launchfile,"w")
			template =  self.loadStartupTemplate()
			content = template%(SMTPLAUNCH_NAME,self.runpath+'smtp.py', 'restart')
			f.write(content)
			f.close()
		except:
			pass
	
	def removeSmtpStartupItem(self):
		try:
			os.remove(os.path.expanduser(STARTUP_DIR+SMTPLAUNCH_FILE))
		except:
			pass
	
	
	def removePopStartupItem(self):
		try:
			os.remove(os.path.expanduser(STARTUP_DIR+POPLAUNCH_FILE))
		except:
			pass

	def mainViewDidLoad(self):
		NSLog('Log:'+SETTINGS_FILE)
		self.config = loadData(SETTINGS_FILE)
		if not self.config:
			NSLog('Using default...')
			self.config = DEFAULT_SETTINGS
		self.popport = self.config['pop3port']
		self.popdelay = self.config['pop3delay']
		self.poplevel = self.config['pop3level']
		self.poplogon = self.config['pop3onlogon']
		self.smtplogon = self.config['smtponlogon']
		self.smtplevel = self.config['smtplevel']
		self.smtpport = self.config['smtpport']
		self.poprunning = isRunning(POP_PID)
		self.smtprunning = isRunning(SMTP_PID)
		self.update()
	
	def didUnselect(self):
		self.stop()
		
	def didSelect(self):
		# We are the selected preference pane. Load the environment.plist.
		self.start()

	def shouldUnselect(self):
		# # The user wants to select another preference pane. If we have
		# 		# unsaved changes ask if they should be saved right now.
		# 		#if self.changed:
		# 			#NSBeginAlertSheet(
		# 				NSLocalizedString("Save changes?", ""),
		# 				NSLocalizedString("Cancel", ""),
		# 				NSLocalizedString("Don't Save", ""),
		# 				NSLocalizedString("Save", ""),
		# 				self.mainView().window(),
		# 				self,
		# 				None,
		# 				"sheetDidDismiss:returnCode:contextInfo:",
		# 				0,
		# 				NSLocalizedString("There are unsaved changed, should these be saved?", ""))
		# 			return NSUnselectLater
		return NSUnselectNow
	
	def read(self):
		NSLog(repr(self.popport))
		NSLog(repr(self.poplogon))
		NSLog(repr(self.popdelay))
		NSLog(repr(self.poplevel))
		self.config['pop3port'] = int(str(self.popport))
		self.config['smtpport'] = int(str(self.smtpport))
		self.config['pop3delay'] = int(str(self.popdelay))
		self.config['pop3level'] = int(str(self.poplevel))
		self.config['smtplevel'] = int(str(self.smtplevel))
		self.config['pop3onlogon']= self.poplogon
		self.config['smtponlogon']= self.smtplogon
		saveData(SETTINGS_FILE,self.config)
		if self.poplogon:
			self.createPopStartupItem()
		else:
			self.removePopStartupItem()
		if self.poplogon:
			self.createSmtpStartupItem()
		else:
			self.removeSmtpStartupItem()

	def popchanged_(self,sender):
		self.read()

	def smtpchanged_(self,sender):
		self.read()
		
	def sheetDidDismiss_returnCode_contextInfo_(self, sheet, code, info):
		# Sheet handler for saving unsaved changes.

		if code == NSAlertDefaultReturn: # 'Cancel'
			self.replyToShouldUnselect_(NSUnselectCancel)
			return

		elif code == NSAlertAlternateReturn: # 'Don't Save'
			pass

		elif code == NSAlertOtherReturn: # 'Save'
			r = self.saveEnvironment()
			if not r:
				self.runAlertSheet(
					NSLocalizedString("Cannot save changes", ""),
					NSLocalizedString("It was not possible to save your changes", ""))
				self.replyToShouldUnselect_(NSUnselectCancel)
				return
		self.replyToShouldUnselect_(NSUnselectNow)
		sheetDidDismiss_returnCode_contextInfo_ = AppHelper.endSheetMethod(sheetDidDismiss_returnCode_contextInfo_)
	
	def outgoing_(self, sender):
		if self.smtprunning:
			 execute(self.runpath,'smtp.py', 'stop')
		else:
			 execute(self.runpath,'smtp.py' ,'restart')

		
	def incoming_(self, sender):
		if self.poprunning:
			 execute(self.runpath,'pop.py', 'stop')
		else:
			 execute(self.runpath,'pop.py' ,'restart')
			


objc.removeAutoreleasePool()
